/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model.util.listas;

/**
 *
 * @author Gustavo Canul
 */
public class DoubleList extends List {

    public void printBack() {
        if (isEmpty()) {

            System.out.println("La lista esta vacia");
        } else {
            System.out.println("La lista es:");
            ListNodeDouble current = (ListNodeDouble) lastNode;

            while (current != null) {
                System.out.println(current.getData().toString() + "<-");
                current = current.getBeforeNode();
            }

        }
    }

    @Override
    public void insertAtBack(Object insertItem) {
        if (isEmpty()) {
            this.firstNode = this.lastNode = new ListNodeDouble(insertItem);

        } else {
            ListNodeDouble nuevo = new ListNodeDouble(insertItem);

        }
    }

    @Override
    public void insertAtFront(Object insertItem) {
        if (isEmpty()) {
            this.firstNode = this.lastNode = new ListNodeDouble(insertItem);
        } else {
            ListNodeDouble nuevo = new ListNodeDouble(insertItem);
            nuevo.setBeforeNode(null);
            nuevo.setNext(firstNode);
            ((ListNodeDouble) this.firstNode).setBeforeNode(nuevo);
            this.firstNode = nuevo;
        }
    }

    @Override
    public void insertInOrder(Object insertItem) {
        /**
         * ***
         * Para insertar un nodo en cualquier posicion de la lista
         */
        if (isEmpty()) {
            this.firstNode = lastNode = new ListNodeDouble(insertItem);
        } else {
            if (firstNode == lastNode) {
                if ((Integer) insertItem > (Integer) firstNode.getData()) {
                    insertAtFront(insertItem);
                } else {
                    insertAtBack(insertItem);
                }
            } else {
                ListNodeDouble current = (ListNodeDouble) this.firstNode;
                ListNodeDouble prev = null;

                while (current != null && (Integer) insertItem < (Integer) current.getData()) {
                    prev = current;
                    current = (ListNodeDouble) current.getNext();
                }

                if (prev == null) {
                    insertAtFront(insertItem);
                } else {
                    if (prev == lastNode) {
                        insertAtBack(insertItem);
                    } else {
                        ListNodeDouble nuevo = new ListNodeDouble(insertItem);
                        prev.setNext(nuevo);
                        nuevo.setNext(current);
                    }
                }
            }
        }
    }

    @Override
    public Object removeFromFront() throws EmptyListException {
        if (isEmpty()) {
            throw new EmptyListException(getName());

        }

        Object removedItem = this.firstNode.getData();
        if (this.firstNode == this.lastNode) {
            firstNode = null;

        } else {
            firstNode = firstNode.getNext();
            ((ListNodeDouble) firstNode).setBeforeNode(null);
        }


        return removedItem;
    }

    @Override
    public Object removeFromBack() throws EmptyListException {
        if (isEmpty()) {
            throw new EmptyListException(getName());

        }

        Object removedItem = this.firstNode.getData();
        if (this.firstNode == this.lastNode) {
            firstNode = lastNode = null;

        } else {
            lastNode = ((ListNodeDouble) lastNode).getBeforeNode();
            lastNode.setNext(null);
        }


        return removedItem;
    }

    @Override
    public Object removeObject(Object elemento) throws EmptyListException {

        /**
         * ***
         * Para remover un nodo en cualquier posicion de la lista
         */
        if (isEmpty()) {
            throw new EmptyListException(getName());
        }


        if ((Integer) this.firstNode.getData() == (Integer) elemento) {
            removeFromFront();
        }

        ListNodeDouble current = (ListNodeDouble) this.firstNode;
        ListNodeDouble prev = current;

        while (current != null) {

            if ((Integer) current.getData() == (Integer) elemento) {
                prev.setNext(current.getNext());
            } else {
                prev = current;
            }

            current = (ListNodeDouble) current.getNext();
        }
        return elemento;
    }
}
